package com.manong.controller;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.manong.aspect.AutoFill;
import com.manong.config.redis.RedisService;
import com.manong.dto.UserRoleDTO;
import com.manong.entity.Role;
import com.manong.entity.User;
import com.manong.service.RoleService;
import com.manong.service.UserService;
import com.manong.utils.JwtUtils;
import com.manong.utils.Result;
import com.manong.utils.SystemConstants;
import com.manong.vo.query.PassVo;
import com.manong.vo.query.RoleQueryVo;
import com.manong.vo.query.UserQueryVo;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import org.springframework.stereotype.Controller;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author Dorr
 * @since 2025-03-03
 */
@RestController
@RequestMapping("/api/user")
public class UserController {

    @Resource
    private UserService userService;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private RoleService roleService;
    @Resource
    private RedisService redisService;
    @Resource
    private HttpServletRequest request;
    @Resource
    private JwtUtils jwtUtils;
    /**
     * 查询所有用户信息
     * @return
     */
    @GetMapping("/listAll")
    public Result get(){
        return Result.ok(userService.list());
    }

    /**
     * 查询用户分页列表
     * @param userQueryVo
     * @return IPage<User>
     */
    @GetMapping("/list")
    public Result list(UserQueryVo userQueryVo){
        //创建分页对象
        IPage<User> page = new Page<User>(userQueryVo.getPageNo(),userQueryVo.getPageSize());
        //调用分页查询方法
        userService.findUserListByPage(page, userQueryVo);
        return Result.ok(page);
    }

    /**
     * 添加用户
     * @param user
     * @return
     */
    @AutoFill(menu = "用户管理", type = "添加")
    @PostMapping("/add")
    @PreAuthorize("hasAuthority('sys:user:add')")
    public Result add(@RequestBody User user){
        User byUsername = userService.findByUsername(user.getUsername());
        if(byUsername!=null){
            return Result.error().message("该登录名称已被使用，请重新输入！");
        }
        //密码加密
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        if(user.getAvatar()==""){
            user.setAvatar(SystemConstants.DEFAULT_AVATAR);
        }
        if(userService.save(user)){
            return Result.ok().message("用户添加成功");
        }else{
            return Result.error().message("用户添加失败");
        }
    }
    /**
     * 修改用户
     * @param user
     * @return Result
     */
    @AutoFill(menu = "用户管理", type = "修改")
    @PutMapping("/update")
    @PreAuthorize("hasAuthority('sys:user:edit')")
    public Result update(@RequestBody User user) {
        //查询用户
        User item = userService.findByUsername(user.getUsername());
        //判断对象是否为空,且查询到的用户ID不等于当前编辑的用户ID，表示该名称被占用
        if (item != null && item.getId() != user.getId()) {
            return Result.error().message("登录名称已被占用！");
        }
        //调用修改用户信息的方法
        if(userService.updateById(user)){
            return Result.ok().message("用户修改成功");
        }
        return Result.error().message("用户修改失败");
    }
    /**
     * 删除用户
     * @param id
     * @return
     */
    @AutoFill(menu = "用户管理", type = "删除")
    @DeleteMapping("/delete/{id}")
    @PreAuthorize("hasAuthority('sys:user:delete')")
    public Result delete(@PathVariable Long id) {
        //调用删除用户信息的方法
        if(userService.deleteById(id)){
            return Result.ok().message("用户删除成功");
        }
        return Result.error().message("用户删除失败");
    }

    /**
     * 获取分配角色列表
     * @param roleQueryVo
     * @return
     */
    @GetMapping("/getRoleListForAssign")
    @PreAuthorize("hasAuthority('sys:user:assign')")
    public Result getRoleListForAssign(RoleQueryVo roleQueryVo){
        //创建分页对象
        IPage<Role> page = new Page<Role>(roleQueryVo.getPageNo(),
                roleQueryVo.getPageSize());
        //调用查询方法
        roleService.findRoleListByUserId(page,roleQueryVo);
        //返回数据
        return Result.ok(page);
    }

    /**
     * 根据用户ID查询该用户拥有的角色列表
     * @param userId
     * @return
     */
    @GetMapping("/getRoleByUserId/{userId}")
    @PreAuthorize("hasAuthority('sys:user:assign')")
    public Result getRoleByUserId(@PathVariable Long userId){
        //调用根据用户ID查询该用户拥有的角色ID的方法
        List<Long> roleIds = roleService.findRoleIdByUserId(userId);
        return Result.ok(roleIds);
    }
    /**
     * 分配角色
     * @param userRoleDTO
     * @return
     */
    @AutoFill(menu = "用户管理", type = "分配角色")
    @PostMapping("/saveUserRole")
    @PreAuthorize("hasAuthority('sys:user:assign')")
    public Result saveUserRole(@RequestBody UserRoleDTO userRoleDTO){
        if (userService.saveUserRole(userRoleDTO.getUserId(),
                userRoleDTO.getRoleIds())) {
            User findusername = userService.findusername(userRoleDTO.getUserId());
            redisService.del(findusername.getUsername());
            return Result.ok().message("角色分配成功");
        }
        return Result.error().message("角色分配失败");
    }
    @AutoFill(menu = "用户管理", type = "重置密码")
    @PutMapping("/Reset")
    @PreAuthorize("hasAuthority('sys:user:reset')")
    public Result Reset(@RequestBody Map<String,Long> userId){
        User user = new User();
        user.setId(userId.get("id"));
        user.setPassword(passwordEncoder.encode("123456"));
        if(!userService.updateById(user)){
            return Result.ok().message("密码重置失败");
        }
        return Result.ok().message("密码重置成功");
    }

    @AutoFill(menu = "个人中心", type = "修改密码")
    @PutMapping("/updatePass")
    public Result updatePass(@RequestBody PassVo pass) {

        String username = jwtUtils.getUsernameFromToken(request.getHeader("token"));
        User byUsername = userService.findByUsername(username);
        if(!passwordEncoder.matches(pass.getOldPassword(), byUsername.getPassword())){
            return Result.error().message("旧密码错误");
        }
        User user = new User();
        user.setId(byUsername.getId());
        user.setPassword(passwordEncoder.encode(pass.getNewPassword()));
        if(!userService.updateById(user)){
            return Result.ok().message("密码修改失败");
        }
        return Result.ok().message("密码修改成功");
    }
}

